package cn.tanghom.support.hook;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.repository.PagingAndSortingRepository;

import cn.tanghom.app.system.model.Config;
import cn.tanghom.app.system.model.User;
import cn.tanghom.app.system.service.DisplayMapping;
import cn.tanghom.support.web.BaseController;
import cn.tanghom.support.web.ContextHolder;

import com.unbiz.common.StringUtil;


/**
 * 
 * @author Hunteron-cp
 *
 * @param <M> is model class
 */
public abstract class AbstractModule<M> implements Comparable<AbstractModule<M>>{
	protected static final Logger logger = LoggerFactory.getLogger(AbstractModule.class);
	protected DisplayMapping display = new DisplayMapping();
	
	public int weight = 0;	//插件的权重，从小到大排序
	public int status = 1;	//状态 1：启用； 0：禁用
	
	protected final Class<?> modelClass;	
	
	public AbstractModule(){	
		modelClass = getParamClazz(this.getClass());
		ModuleManager.registerModule(modelClass,this);
	}	
	
	public String getName(){
		return "<AbstractModule>";
	}
	
	/**
	 * 获取M的class
	 * 
	 * @return M
	 */
	@SuppressWarnings("unchecked")
	public final Class<?> getParamClazz(Class<?> cls) {
		Type t = cls.getSuperclass().getGenericSuperclass();
		Type[] params = ((ParameterizedType) t).getActualTypeArguments();
		return (Class<?>) params[0];
	}
	
	public void handleError(String method,Exception e){
		logger.error("call "+method+" fail on "+ this.getClass().getName() ,e);
	}
	
	public void handleWarn(String method, String msg){
		logger.warn("call "+method+" has warning on "+ this.getClass().getName()+" : "+msg);
	}
	
	public int compareTo(AbstractModule<M> arg) {  
		return this.weight - arg.weight;  
	}	
	
	public void config(String name,String title,String value){
		String model = StringUtil.toLowerCase4First(modelClass.getSimpleName());
		config(model,name,title);
	}
	
	public void config(String model,String name,String title,String value){
		Config config = new Config();
		config.setGroupKey(model);
		config.setConfigKey(name);
		config.setName(title);		
		config.setValue(value);	
		display.attach(config);	
	}
	
	
	public boolean init() { 
		return true;
	}  
	
	/**
	 * 判断是否继续执行hook
	 * @param method
	 * @param params
	 * @return
	 */
	public boolean hook(String method, Object... params) { 
		return true;
	}  
	
	/**
	 * 当模型加载时，触发
	 * 
	 */
	public boolean loadModel(M model) { 
		return false;
	} 
	
	/**
	 * 验证操作,在保存前执行
	 * op: update or save
	 */
	public boolean validateModel(M model,BaseController c,String op) {
		return true;
	}
	
	//when model updated
	public boolean updateModel(M model,BaseController c) { 
		return false;
	} 
	
	//when model created
	public boolean saveModel(M model,BaseController c) { 
		return false;
	} 
	
	//when model deleted
	public boolean deleteModel(M model,BaseController c) { 
		return false;
	} 
	
	// 详情显示页
	public boolean viewModel(M model,  BaseController c){
		return true;
	}
	
	// 列表显示页
	public boolean listModel(List<M> list, BaseController c){
		return true;
	}	
	
	/**
	 * 获取当前登录管理员(从数据库中加载),若未登录则返回null.
	 *
	 * @return 当前登录管理员对象
	 */
	/**
	 * 获取当前登录管理员,若未登录则返回null.
	 *
	 * @return 当前登录管理员ID
	 */
	public User getLoginUser() {
		return ContextHolder.getUser();
	}
}
